package com.mf.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.mf.bo.DateScopedBo;
import com.mf.bo.ImportExcelBo;
import com.mf.entity.CodeHistory;
import com.mf.result.Result;
import com.mf.service.ICodeHistoryService;
import com.mf.utils.DateUtil;
import com.mf.vo.ImportExcelVo;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: lmf
 * @Create: 2024/7/13 8:24
 * Description: 导入excel计算
 */
@Slf4j
@RestController
@RequestMapping("import")
public class ImportCalculate {
    @Resource
    private ICodeHistoryService codeHistoryService;

    @Operation(summary = "导入需要更新的数据")
    @PostMapping("importExcel")
    public Result<String> importExcel(@Valid @RequestBody ImportExcelBo importExcelBo) {
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(importExcelBo.getImportPath());
            List<Map<Integer, Object>> list = EasyExcel.read(inputStream)
                    .excelType(ExcelTypeEnum.XLSX)
                    .sheet(0)
                    .doReadSync();

            List<ImportExcelVo> importExcelVo = getImportExcelVo(list);

            // 获取历史数据
            String date = StringUtils.isBlank(importExcelBo.getDate()) ? DateUtil.getToDate() : importExcelBo.getDate();
            DateScopedBo dateScopedBo = new DateScopedBo(date, date);
            List<CodeHistory> codeHistories = codeHistoryService.getCodeHistories(dateScopedBo);


            for (ImportExcelVo excelVo : importExcelVo) {
//                if ("1".equals(excelVo.getIsSell())) {
//                    continue;
//                }
                CodeHistory codeHistory = getCodeHistory(excelVo, codeHistories);
                if (codeHistory != null) {
                    // 计算当日收益
                    excelVo.setDayProfit(setPercentage(codeHistory.getC().subtract(excelVo.getLatestPrice()).divide(excelVo.getLatestPrice(), 4,
                            RoundingMode.FLOOR)));
                    // 设置止盈价格 (买入价格 * 1.003)
                    excelVo.setProfitPrice(excelVo.getBuyPrice().multiply(BigDecimal.valueOf(1.003)).setScale(2, RoundingMode.FLOOR));
                    // 设置止损价格 (买入价格 * 0.95)
                    excelVo.setLossPrice(excelVo.getBuyPrice().multiply(BigDecimal.valueOf(0.95)).setScale(2, RoundingMode.FLOOR));
                    // 设置最新价格
                    excelVo.setLatestPrice(codeHistory.getC());
                    if (!"1".equals(excelVo.getIsSell())) {
                        // 重新计算最新收益  (最新价格 - 买入价格) / 买入价格
                        excelVo.setLatestProfit(setPercentage(excelVo.getLatestPrice().subtract(excelVo.getBuyPrice()).divide(excelVo.getBuyPrice(), 4,
                                RoundingMode.FLOOR)));
                    }

                }
            }

            // 将数据在按照模板导出
            EasyExcel.write(importExcelBo.getExportPath())
                    .withTemplate(importExcelBo.getTemplatePath())
                    .sheet()
                    .doFill(importExcelVo);


        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }

        return Result.success(null);
    }

    /**
     * 转换百分比
     */
    private String setPercentage(BigDecimal value) {
        return value.multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.FLOOR) + "%";
    }

    /**
     * 获取对应股票历史数据
     */
    private CodeHistory getCodeHistory(ImportExcelVo excelVo, List<CodeHistory> codeHistories) {
        for (CodeHistory codeHistory : codeHistories) {
            if (codeHistory.getDm().equals(excelVo.getDm())) {
                return codeHistory;
            }
        }
        return null;
    }


    /**
     * 获取导入的vo
     */
    private List<ImportExcelVo> getImportExcelVo(List<Map<Integer, Object>> list) {
        List<ImportExcelVo> importExcelVos = new ArrayList<>();
        for (Map<Integer, Object> map : list) {
            ImportExcelVo importExcelVo = new ImportExcelVo();
            if (map.get(1) == null) {
                continue;
            }
            String isSell = setValue(map.get(10), "0");
//            if(!"1".equals(isSell)){
            for (int i = 0; i < 11; i++) {
//                importExcelVo.setIsProfit(map.get(0).toString());
                // 股票代码 dm
                importExcelVo.setDm(setValue(map.get(0), "0"));
                // 买入价格 buyPrice
                importExcelVo.setBuyPrice(new BigDecimal(setValue(map.get(1), "1")));
                // 推荐日期 recommendDate
                importExcelVo.setRecommendDate(setValue(map.get(2), "0"));
                // 最新价格 latestPrice
                importExcelVo.setLatestPrice(new BigDecimal(setValue(map.get(3), "1")));
                // 止盈价格 profitPrice
//                    importExcelVo.setProfitPrice(new BigDecimal(setValue(map.get(4), "1")));
                // 最新收益
                importExcelVo.setLatestProfit(setValue(map.get(6), "0"));
                // 卖出价格 sellPrice
                importExcelVo.setSellPrice(new BigDecimal(setValue(map.get(9), "1")));
                // 卖出收益 sellProfit
                importExcelVo.setSellProfit(setValue(map.get(10), "0"));

                // 备注 remark
                importExcelVo.setRemark(setValue(map.get(8), "0"));
                // 是否卖出 isSell
                importExcelVo.setIsSell(setValue(map.get(11), "0"));
            }
            importExcelVos.add(importExcelVo);
//            }

        }
        return importExcelVos;
    }

    private String setValue(Object value, String type) {
        if ("0".equals(type)) {
            return value != null ? value.toString() : "";
        } else {
            return value != null ? value.toString() : "0";
        }
    }


}
